本篇是實作常用的 AWS KMS 服務之 Terraform 模組,並且會使用到 YAML 資料結構來定義模組的內容,完整的專案程式碼分享在我的 Github 上。
./configs/kms/keys.yaml
、放置 KMS Policy JSON 檔案的目錄 ./configs/kms/policies
和模組 my_kms
的放置位置 modules/my_kms
:├── configs
│ ├── cloudfront
│ │ └── distributions.yaml
│ ├── cloudwatch
│ │ └── loggroups.yaml
│ ├── iam
│ │ ├── assume_role_policies
│ │ ├── policies
│ │ ├── role_policies
│ │ ├── user_policies
│ │ └── iam.yaml
│ ├── kinesis
│ │ ├── policies
│ │ └── streams.yaml
│ ├── kms
│ │ └── keys.yaml
│ ├── s3
│ │ ├── policies
│ │ └── s3.yaml
│ ├── subnet
│ │ └── my-subnets.yaml
│ └── vpc
│ └── my-vpcs.yaml
├── example.tfvars
├── locals.tf
├── main.tf
├── modules
│ ├── my_cloudfront
│ ├── my_cloudwatch
│ ├── my_eips
│ ├── my_eventbridge
│ ├── my_iam
│ ├── my_igw
│ ├── my_instances
│ ├── my_kinesis_stream
│ ├── my_kms
│ │ ├── kms_alias.tf
│ │ ├── kms_key.tf
│ │ ├── outputs.tf
│ │ ├── provider.tf
│ │ └── variables.tf
│ ├── my_nacls
│ ├── my_route_tables
│ ├── my_s3
│ ├── my_subnets
│ └── my_vpc
└── variables.tf
./configs/kms/keys.yaml
內容來定義 KMS 需要用建立的資源:kms:
- alias_name: "alias/<ALIAS_NAME>"
customer_master_key_spec: "<CUSTOMER_MASTER_KEY_SPEC>"
enable_key_rotation: <true or false>
is_enabled: <true or flase>
key_usage: "SIGN_VERIFY"
multi_region: <true or false>
policy_file: "<POLICY_FILE_PATH>"
tagsName: "<KEY_NAME_WITH_TAG>"
my_kms
模組:./modules/my_kms/outputs.tf
:output "kms_key_id" {
value = aws_kms_key.kms
}
output "kms_key_alias" {
value = aws_kms_alias.kms
}
./modules/my_kms/provider.tf
:provider "aws" {
region = var.aws_region
profile = var.aws_profile
}
./modules/my_kms/variables.tf
:variable "aws_region" {
description = "AWS region"
default = "ap-northeast-1"
}
variable "aws_profile" {
description = "AWS profile"
default = ""
}
variable "project_name" {
type = string
description = "Project name"
default = ""
}
variable "department_name" {
type = string
description = "Department name"
default = "SRE"
}
variable "environment" {
type = string
default = ""
}
variable "kms_path" {
description = "The path of configuration file"
default = ""
}
./modules/my_kms/kms_alias.tf
:resource "aws_kms_alias" "kms" {
for_each = { for r in local.kms : r.tagsName => r }
name = each.value.alias_name
target_key_id = aws_kms_key.kms[each.value.tagsName].id
}
./modules/my_kms/kms_key.tf
:locals {
kms = yamldecode(file("${var.kms_path}"))["kms"]
}
resource "aws_kms_key" "kms" {
for_each = { for r in local.kms : r.tagsName => r }
customer_master_key_spec = each.value.customer_master_key_spec
description = lookup(each.value, "description", "")
enable_key_rotation = each.value.enable_key_rotation
is_enabled = each.value.is_enabled
key_usage = each.value.key_usage
multi_region = each.value.multi_region
policy = file("${each.value.policy_file}")
tags = {
Name = each.value.tagsName
Department = var.department_name
Env = var.environment
Project = var.project_name
}
tags_all = {
Name = each.value.tagsName
Department = var.department_name
Env = var.environment
Project = var.project_name
}
}
example.tfvars
:aws_region="ap-northeast-1"
aws_profile="<YOUR_PROFILE>"
project_name="example"
department_name="SRE"
main.tf
:terraform {
required_providers {
aws = {
version = "5.15.0"
}
}
backend "s3" {
bucket = "<YOUR_S3_BUCKET_NAME>"
dynamodb_table = "<YOUR_DYNAMODB_TABLE_NAME>"
key = "terraform.tfstate"
region = "ap-northeast-1"
shared_credentials_file = "~/.aws/config"
profile = "<YOUR_PROFILE>"
}
}
其他模組省略...
# kms
module "kms" {
aws_profile = var.aws_profile
aws_region = var.aws_region
department_name = var.department_name
project_name = var.project_name
environment = var.environment
kms_path = "./configs/kms/keys.yaml"
source = "./modules/my_kms"
}
kms:
- alias_name: "alias/my-key"
customer_master_key_spec: "RSA_2048"
enable_key_rotation: true
is_enabled: true
key_usage: "SIGN_VERIFY"
multi_region: false
policy_file: "./configs/kms/policies/my-key-policy.json"
tagsName: "my-key"
terraform init && terraform plan --out .plan -var-file=example.tfvars
來確認一下結果:
...
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.kms.aws_kms_alias.kms["my-key"] will be created
+ resource "aws_kms_alias" "kms" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "alias/my-key"
+ name_prefix = (known after apply)
+ target_key_arn = (known after apply)
+ target_key_id = (known after apply)
}
# module.kms.aws_kms_key.kms["my-key"] will be created
+ resource "aws_kms_key" "kms" {
+ arn = (known after apply)
+ bypass_policy_lockout_safety_check = false
+ customer_master_key_spec = "RSA_2048"
+ description = (known after apply)
+ enable_key_rotation = true
+ id = (known after apply)
+ is_enabled = true
+ key_id = (known after apply)
+ key_usage = "SIGN_VERIFY"
+ multi_region = false
+ policy = jsonencode(
{
+ Id = "key-consolepolicy-3"
+ Statement = []
+ Version = "2012-10-17"
}
)
+ tags = {
+ "Department" = "SRE"
+ "Env" = "develop"
+ "Name" = "my-key"
+ "Project" = "example"
}
+ tags_all = {
+ "Department" = "SRE"
+ "Env" = "develop"
+ "Name" = "my-key"
+ "Project" = "example"
}
}
...
Plan: 49 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: .plan
To perform exactly these actions, run the following command to apply:
terraform apply ".plan"
Releasing state lock. This may take a few moments...
下一篇文章將會展示實作 AWS MSK 之 Terraform 模組。